/* lflRead.c  -  lfRead */

#include <xinu.h>

/*------------------------------------------------------------------------
 * lflRead  --  read from a previously opened local file
 *------------------------------------------------------------------------
 */
devcall	lflRead (
	  struct dentry *devptr,	/* entry in device switch table */
	  char	*buff,			/* buffer to hold bytes		*/
	  int32	count			/* max bytes to read		*/
	)
{
	uint32	numread;		/* number of bytes read		*/
	int32	nxtbyte;		/* character or SYSERR/EOF	*/
	
	struct	lflcblk	*lfptr;		/* ptr to open file table entry	*/
	struct	ldentry	*ldptr;		/* ptr to file's entry in the	*/
								/*  in-memory directory		*/

	//kprintf("Read begins!\r\n");
	
	if (count < 0) {
		signal(lfptr->lfmutex);
		return SYSERR;
	}

	for (numread=0 ; numread < count ; numread++) {
		lfptr = &lfltab[devptr->dvminor];
		wait(lfptr->lfmutex);
		if (lfptr->lfstate != LF_USED) {
			signal(lfptr->lfmutex);
			nxtbyte = SYSERR;
		}
		ldptr = lfptr->lfdirptr;
		if (lfptr->lfpos >= ldptr->ld_size) {
			signal(lfptr->lfmutex);
			nxtbyte = EOF;
		}
		if (lfptr->lfbyte >= &lfptr->lfdblock[LF_BLKSIZ]) {
			lfsetup(lfptr);
		}
		nxtbyte = 0xff & *lfptr->lfbyte++;
		lfptr->lfpos++;
		signal(lfptr->lfmutex);
		if (nxtbyte == SYSERR) {
			//kprintf("nxtbyte == SYSERR\r\n");
			return SYSERR;
		} else if (nxtbyte == EOF) {	/* EOF before finished */
		    if (numread == 0) {
			//kprintf("nxtbyte = EOF and numread = 0\r\n");
			return EOF;
		    } else {
			//kprintf("nxtbyte = EOF and numread = %d\r\n", numread);
			return numread;
		    }
		} else {
			*buff++ = (char) (0xff & nxtbyte);
			//kprintf("Read %c\r\n", *buff);
		}
	}
	return numread;
}
